﻿#include "tcpsession.h"
#include "tcpserver.h"
extern "C" {
#include <sys/types.h>
#include <sys/socket.h>
}
#include "mydb.h"
#include "json11.hpp"

TcpSession::TcpSession(clientData *cd): cd(cd) {
    this->start();
}

TcpSession::~TcpSession() {
    //closeConnect();
}

void TcpSession::run() {
    int rdSize = 0;
    char buf[512];
    string msg;
    while (1) {
        memset(buf, 0, strlen(buf));
        rdSize = recv(cd->clientFd, buf, MAX_SIZE, 0); // 从客户端接收数据
        msg = buf;
        cout << "msg::" << msg << endl;
        switch(getValueInt(&msg, "type")) {
            case LOGIN: {
                clientLogin(&msg);
                break;
            }
            case COMMODITY: {
                getCommodityList(msg);
                break;
            }
            case ORDER: {
                submitOrder(msg);
                break;
            }
            case QUIT: {
                closeConnect();
                delete this;
                return ;
            }
            case EXIT: {
                closeConnect();
                delete this;
                return ;
            }
            case AMOUNT: {
                updateAmount(msg);
                break;
            }
            default:
                break;
        }
        // 客户端断开连接
        if (rdSize <= 0) {
            closeConnect();
            delete this;
            return ;
        }

        displayAllClient();  // 打印全部客户端信息
    }

}

void TcpSession::closeConnect() {
    pthread_mutex_lock(&mutex);  // 加锁
    close(cd->clientFd);
    for (int i = 0; i < (int)clientArray->size(); i++) {
        if((*clientArray)[i]->clientId == cd->clientId) {
            clientArray->erase(clientArray->begin() + i);  // 删除指定位置元素
            delete cd;
        }
    }
    pthread_mutex_unlock(&mutex);  // 解锁
}

void TcpSession::displayAllClient() {
    cout << "=============displayAllClient=============" << endl;
    for (int i = 0; i < (int)clientArray->size(); i++) {
        cout << "clientId=" << (*clientArray)[i]->clientId << endl;
        cout << "clientFd=" << (*clientArray)[i]->clientFd << endl;
        cout << "ip=" << (*clientArray)[i]->ip << endl;
        cout << "port=" << (*clientArray)[i]->port << endl;
        cout << endl;
    }
    cout << "=============displayAllClient=============" << endl;
}

string TcpSession::getValueStr(string *msg, const char *key) {
    string err;
    auto json = Json::parse(*msg, err);
    return json[key].string_value();
}

int TcpSession::getValueInt(string *msg, const char *key) {
    string err;
    auto json = Json::parse(*msg, err);
    return json[key].int_value();
}

void TcpSession::clientLogin(string *json) {
    string account = getValueStr(json, "account");
    string password = getValueStr(json, "password");
    string sql = "select * from member where account ='" + account + "' and password = '" + password + "';";
    string result;
    MyDB::getDB()->selectData(&sql, &result);
    string msg = "{\"type\":1,\"result\":" + result + "}";
    serverSingleMsg(msg);
    cout << msg << endl;
}

// 服务器单发数据
void TcpSession::serverSingleMsg(string &msg) {
    send(cd->clientFd, msg.c_str(), msg.length(), 0); // 向其他客户端发送数据
}

void TcpSession::getCommodityList(string &json) {
    int page = getValueInt(&json, "page");
    int startPos =  (page - 1) * 6;
    string sql = "select commodity_id,name,picture,output_price,amount from commodity limit " + to_string(startPos) + ",6;";
    string result;
    MyDB::getDB()->selectData(&sql, &result);
    string msg = "{\"type\":2,\"result\":" + result + "}";
    serverSingleMsg(msg);
    cout << msg << endl;
}

void TcpSession::submitOrder(string &json) {
    int memberId = getValueInt(&json, "member_id");
    string sql;
    // 新增一个当前用户未支付的订单
    sql = "INSERT INTO `shop`.`order` VALUES(NULL," + to_string(memberId) + ",NULL,NULL,0,NOW(),NOW());";
    if(!MyDB::getDB()->updateData(&sql)) {
        cout << "insert order error" << endl;
        return ;
    }

    // 查询获取刚刚生成的订单id
    sql = "select order_id from `shop`.`order` where member_id = " + to_string(memberId) + " and pay_state = 0 ;";
    string result;
    MyDB::getDB()->selectData(&sql, &result);
    //string msg = "{\"type\":3,\"result\":" + result + "}";
    string err;
    auto pjson = Json::parse(result, err);
    // json格式正确&&能查到数据
    if(!err.empty() || pjson.array_items().empty()) {
        cout << "获取数据失败" << endl;
        return ;
    }
    string order_id;
    for (auto &k : pjson.array_items() ) {
        order_id = k["order_id"].string_value();
        break;
    }

    // 添加订单项
    auto oiJson = Json::parse(json, err);
    // json格式正确&&能查到数据
    if(!err.empty() || oiJson["item"].array_items().empty()) {
        cout << "获取数据失败" << endl;
        return ;
    }
    for (auto &k : oiJson["item"].array_items() ) {
        sql = "INSERT INTO `shop`.`order_item` VALUES("
              + order_id
              + "," + to_string(k["id"].int_value())
              + "," + to_string(k["num"].int_value()) + ");";
        if(!MyDB::getDB()->updateData(&sql)) {
            cout << "insert order item error" << endl;
            return ;
        }
    }

    // 修改订单信息，增加总价，支付状态改为已支付
    string sum = getValueStr(&json, "sum");
    sql = "UPDATE `shop`.`order` SET pay_sum = " + sum
          + ", pay_state = 1 WHERE order_id = " + order_id + ";";
    cout << "update order :" << sql << endl;
    if(!MyDB::getDB()->updateData(&sql)) {
        cout << "update order error" << endl;
        return ;
    }
}

void TcpSession::updateAmount(string &json) {
    string commodity_id = getValueStr(&json, "id");
    string amount = getValueStr(&json, "amount");
    string sql = "UPDATE `shop`.`commodity` SET amount = " + amount
                 + " WHERE commodity_id = " + commodity_id + "; ";
    cout << "update order :" << sql << endl;
    if(!MyDB::getDB()->updateData(&sql)) {
        cout << "update amount error" << endl;
        return ;
    }
}

